package icu.zhhll.redis;

import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.io.IOException;
import java.io.InputStream;
import java.time.Duration;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;

/**
 * @author zh
 * @date 2023/9/15 17:14
 */
final class SingletonJedisHolder {

    // volatile保证原子性
    private static volatile SingletonJedisHolder instance = null;
    private final JedisPool pool;

    private SingletonJedisHolder(Properties properties) {
        // Jedis连接池配置
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        // 最大空闲连接数, 默认8个
        jedisPoolConfig.setMaxIdle(100);
        // 最大连接数, 默认8个
        jedisPoolConfig.setMaxTotal(500);
        //最小空闲连接数, 默认0
        jedisPoolConfig.setMinIdle(0);
        // 获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间,  默认-1
        jedisPoolConfig.setMaxWait(Duration.ofSeconds(2)); // 设置2秒
        //对拿到的connection进行validateObject校验
        jedisPoolConfig.setTestOnBorrow(true);


        String host = properties.getProperty("redis.host", "127.0.0.1:6379");
        Set<HostAndPort> hostAndPortsSet = new HashSet<>();

        String[] splitHostPort = host.split(":");
        pool = new JedisPool(jedisPoolConfig, splitHostPort[0],
                Integer.parseInt(splitHostPort[1]));

    }

    public static SingletonJedisHolder getInstance() {
        if (instance == null) {
            synchronized (RedisFIFOCache.class) {
                if (instance == null) {
                    Properties properties = readProp();
                    instance = new SingletonJedisHolder(properties);
                }
            }
        }

        return instance;
    }

    /**
     * 读取redis配置文件
     *
     * @return
     */
    private static Properties readProp() {

        Properties prop = new Properties();
        try (InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream("redis.properties")) {
            prop.load(stream);
        } catch (IOException e) {
            throw new RuntimeException("读取redis.properties失败", e);
        }

        return prop;
    }

    public JedisPool getPool() {
        return pool;
    }
}
